package com.idas.comp;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.idas.common.Util;
import com.idas.comp.enums.ExpenseStatus;
import com.idas.comp.enums.ResourceType;

public class Expense extends Resource {
	private String userUUID;
	private String moduleUUID;
	private long startTimestamp;
	private long endTimestamp;
	private ExpenseStatus status;

	public Expense() {
	}

	protected Expense(ResultSet rs) throws SQLException {
		userUUID = rs.getString("user_uuid");
		moduleUUID = rs.getString("module_uuid");
		startTimestamp = rs.getLong("start_timestamp");
		endTimestamp = rs.getLong("end_timestamp");
		status = ExpenseStatus.getValue(rs.getInt("expstatus_id"));
	}

	public String getUserUUID() {
		return userUUID;
	}

	public void setUserUUID(String userUUID) {
		this.userUUID = userUUID;
	}

	public void setUserUUID(Connection conn, String userUUID)
			throws SQLException {
		String sql = "UPDATE expense SET user_uuid = ? WHERE uuid = ?";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, userUUID);
		ps.setString(2, super.getUuid());
		ps.execute();
		ps.close();
		setUserUUID(userUUID);
	}

	public String getModuleUUID() {
		return moduleUUID;
	}

	public void setModuleUUID(String moduleUUID) {
		this.moduleUUID = moduleUUID;
	}

	public void setModuleUUID(Connection conn, String moduleUUID)
			throws SQLException {
		String sql = "UPDATE expense SET module_uuid = ? WHERE uuid = ?";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, moduleUUID);
		ps.setString(2, super.getUuid());
		ps.execute();
		ps.close();
		setModuleUUID(moduleUUID);
	}

	public long getStartTimestamp() {
		return startTimestamp;
	}

	public void setStartTimestamp(long startTimestamp) {
		this.startTimestamp = startTimestamp;
	}

	public void setStartTimestamp(Connection conn, long startTimestamp)
			throws SQLException {
		String sql = "UPDATE expense SET start_timestamp = ? WHERE uuid = ?";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setLong(1, startTimestamp);
		ps.setString(2, super.getUuid());
		ps.execute();
		ps.close();
		setStartTimestamp(startTimestamp);
	}

	public long getEndTimestamp() {
		return endTimestamp;
	}

	public void setEndTimestamp(long endTimestamp) {
		this.endTimestamp = endTimestamp;
	}

	public void setEndTimestamp(Connection conn, long endTimestamp)
			throws SQLException {
		String sql = "UPDATE expense SET end_timestamp = ? WHERE uuid = ?";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setLong(1, endTimestamp);
		ps.setString(2, super.getUuid());
		ps.execute();
		ps.close();
		setEndTimestamp(endTimestamp);
	}

	public ExpenseStatus getStatus() {
		return status;
	}

	public void setStatus(ExpenseStatus status) {
		this.status = status;
	}

	public void setStatus(Connection conn, ExpenseStatus status)
			throws SQLException {
		String sql = "UPDATE expense SET expstatus_id = ? WHERE uuid = ?";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setInt(1, ExpenseStatus.getValue(status));
		ps.setString(2, super.getUuid());
		ps.execute();
		ps.close();
		setStatus(status);
	}
	
	public static Expense createExpense(Connection conn, UserAccess uac, Expense newExp) throws Exception{
		
		Module mod = Module.getModuleForUser(conn, newExp.getModuleUUID(), uac.getUserId());
		
		if(null == mod){
			throw new Exception("User is not registered for module");
		}
		
		if(!Util.vaildateTimestamp(newExp.getStartTimestamp())){
			throw new Exception("Invaild start time, has this happened yet?");
		}
		
		if(!Util.vaildateTimestamp(newExp.getEndTimestamp())){
			throw new Exception("Invaild end time, has this happened yet?");
		}
		
		String sql = "INSERT INTO expense (user_uuid, module_uuid, start_timestamp, end_timestamp, expstatus_id) VALUES (?,?,?,?,?)";
		PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
		ps.setString(1, uac.getUser().getUuid());
		ps.setString(2, newExp.getModuleUUID());
		ps.setLong(3, newExp.getStartTimestamp());
		ps.setLong(3, newExp.getEndTimestamp());
		ps.execute();
		ResultSet rs = ps.getGeneratedKeys();
		
		long expId = -1;
		
		while(rs.next()){
			expId = rs.getLong(1);
		}
		
		rs.close();
		ps.close();
		
		String uuid = Util.generateResourceUUID(ResourceType.EXPENSE, expId, uac.getUserId());
		
		Resource res = Resource.addResourceToDatabase(conn, uuid, "Expense Claim for module "+mod.getCode(), uac.getUserId(), ResourceType.EXPENSE);
		
		if(null==res){
			throw new Exception("Failed to create expense");
		}
		
		sql = "UPDATE expense SET uuid = ? WHERE expense_id = ?";
		ps = conn.prepareStatement(sql);
		ps.setString(1, uuid);
		ps.setLong(2, expId);
		ps.execute();
		ps.close();
		
		return getExpenseForUUID(conn, uuid);
		
	}

	public static Expense getExpenseForUUID(Connection conn, String uuid)
			throws SQLException {
		Expense exp = null;

		String sql = "SELECT * FROM su.* e.* FROM system_uuid su, expense e WHERE su.system_uuid = ? AND su.system_uuid = e.uuid";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, uuid);
		ResultSet rs = ps.executeQuery();
		while (rs.next()) {
			exp = new Expense(rs);
		}
		rs.close();
		ps.close();
		return exp;
	}
}
